#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
# GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
# Author: Shawn.Tan
# Date: 2025.10.28
#
# History: Initial Version 2025.10.28
#
#
from DV.gpgpu.trees.instruction_tree import LDST32_All_instructions
from DV.gpgpu.trees.instruction_tree import LDST_All_instructions
from DV.gpgpu.trees.instruction_tree import LDST_Byte_instructions
from DV.gpgpu.trees.instruction_tree import LDST_Double_instructions
from DV.gpgpu.trees.instruction_tree import LDST_Half_instructions
from DV.gpgpu.trees.instruction_tree import LDST_Word_instructions
from base.Sequence import Sequence
from gpgpu.EnvGPGPU import EnvGPGPU
from gpgpu.GenThreadGPGPU import GenThreadGPGPU


class MyMainSequence(Sequence):
    """"""

    def generate(self, **kargs):

        for _ in range(100):
            if self.getGlobalState("AppRegisterWidth") == 32:
                instr = self.pickWeighted(LDST32_All_instructions)
            else:
                instr = self.pickWeighted(LDST_All_instructions)

            # Get two adjacent 4K pages.
            page_addr = self.genVA(Size=0x2000, Align=0x1000)

            min_addr_offset = self._get_min_address_offset(instr)
            target_addr = page_addr + self.random32(min_addr_offset, 0xFFF)

            self.genInstruction(instr, {"LSTarget": target_addr})

            self.notice(">>>>>  Instruction: {}   Target addr: {:012x}".format(instr, target_addr))

    def _get_min_address_offset(self, instr):
        # To generate page crossings, for the target address to be at the
        # end of the first page setting the page offset to some value close
        # to the end of the page based on the size of the target operand of
        # the selected instruction.  The code below will generated some
        # page crossings and some accesses that are at the end of the page,
        # but not crossing the page.
        min_addr_offset = 0
        if (instr in LDST_Byte_instructions) or (instr in LDST_Half_instructions):
            min_addr_offset = 0xFFC
        elif instr in LDST_Word_instructions:
            min_addr_offset = 0xFFA
        elif instr in LDST_Double_instructions:
            min_addr_offset = 0xFF6
        else:
            self.error(">>>>>  Hmmm...  {} is an unexpected instruction.".format(instr))

        return min_addr_offset


MainSequenceClass = MyMainSequence
GenThreadClass = GenThreadGPGPU
EnvClass = EnvGPGPU
